package block

import (
	"bytes"
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"crypto/sha256"
	"fmt"
	"github.com/btcsuite/btcutil/base58"
	"golang.org/x/crypto/ripemd160"
	"log"
)

//1. 创建一个结构walletKeyPair秘要对，保存公钥和私钥
//2.给这个结构提供一个方法GetAddress，私钥-》公钥-》地址

type WalletKeyPair struct {
	PrivateKey *ecdsa.PrivateKey
	PublicKey  []byte
	/**
	type PublicKey struct {
		elliptic.Curve
		X, Y *big.Int
	}
	*/
}

//创建一个钱包
func NewWalletKeyPair() *WalletKeyPair {
	privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
	if err != nil {
		log.Panic(err)
	}


	publicKeyRaw := privateKey.PublicKey
	publicKey := append(publicKeyRaw.X.Bytes(), publicKeyRaw.Y.Bytes()...)

		pbyte:=privateKey.D.Bytes()
		paddress:=base58.Encode(pbyte)
		fmt.Println("测试私钥：",paddress)


	return &WalletKeyPair{
		PrivateKey: privateKey,
		PublicKey:  publicKey,
	}
}

// 传入公钥 返回ripemd160加密公钥哈希
func (w *WalletKeyPair) GetAddress() string {

	publicHash :=HashPubHash(w.PublicKey)
	version := 0x00
	//21字节数据
	payload := append([]byte{byte(version)}, publicHash...)

	checksum := CheckSum(payload)

	payload = append(payload, checksum...)

	address:=base58.Encode(payload)
	return address
}
//校验用户输入的base58公钥哈希是否正确
func IsValidAddress(address string) bool {
	// 将输入的地址进行解码得到25字节
	// 取出前21字节，运行checksum函数，得到checksum1
	// 取出后4字节，得到checksum2
	// 比较 得到checksum1和得到checksum2

	decodeInfo:=base58.Decode(address)
	if len(decodeInfo)!=25 {
		return false
	}
	payLoad:=decodeInfo[0:len(decodeInfo)-4]
	checksum1:=CheckSum(payLoad)
	checksum2:=decodeInfo[len(decodeInfo)-4:]

	return bytes.Equal(checksum1,checksum2)
}

func HashPubHash(from []byte) []byte {
	hash := sha256.Sum256(from)
	//创建hash160对象
	//向hash160中write数据
	//做哈希运算
	rip160Haher := ripemd160.New()
	_, err := rip160Haher.Write(hash[:])
	if err != nil {
		log.Panicln(err)
	}
	//sum会和bapp到一起返回byte
	publicHash := rip160Haher.Sum(nil)
	return publicHash;
}

func CheckSum(payload []byte)[]byte  {
	first := sha256.Sum256(payload)
	second := sha256.Sum256(first[:])
	checksum := second[0:4]
	return checksum
}